import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)
import java.util.List;
/**
 * esta es la clase principal donde se lleva a cabo el juego
 * 
 * @author (Octavio y Cesar) 
 * @version (2014.11.28)
 */
public class Space extends World
{   
    private static final GreenfootImage bgImage = new GreenfootImage("space2.jpg");
    private Hero h;
    private Timer time;
    private int scrollSpeed;
    private GreenfootImage imagenG;
    private GreenfootImage scrollingImage;
    private int scrollPosition = 0;
    private boolean pause;
    private GreenfootSound musicGame;
    private Counter puntos;
    private Counter vidas;
    private Counter salud;
    private Counter nivel;
    private List ghostList;
    private List phantomList;
    private List bansheeList;
    private List spiritList;
    private boolean level1;
    private boolean level2;
    private boolean level3;
    private int level;
    private Message m;
    /**
     * Constructor for objects of class Space.
     * 
     */
    public Space()
    { 
        // Create a new world with 600x400 cells with a cell size of 1x1 pixels.

        super(600, 400, 1,false); 
        h=new Hero();
        time=new Timer();
        scrollSpeed=1;
        vidas= new Counter("Lives: ");
        puntos= new Counter("Points: ");
        salud= new Counter("Health: ");
        nivel= new Counter("Level: ");
        bgImage.scale(800,600);
        pause=true;
        GreenfootImage background = new GreenfootImage(600, 400);
        
        scrollingImage = getScrollingImage(800, 600);
        background.drawImage(scrollingImage, 0, 0);
        setBackground(background);
        musicGame= new GreenfootSound("music_menu.wav");
        setPaintOrder(ScoreBoard.class,Message.class,Counter.class,Hero.class, Enemy.class);
 
        prepare();
        appearsGhost();
        level=1;
    }

     /**
      * metodo principal que se ejecuta todo el tiempo
      * se asignan los valores que deben tomar los Counter
      * y el scroll
      */
    public void act()
    {
        vidas.setValue(h.getLives());
        puntos.setValue(h.getPoints());
        salud.setValue(h.getHealth());
        nivel.setValue(level);
        scroll();
        cambiaSpeedScroll(25);
        this.levels();
        this.started();
        
    }
   
     /**
    *checa la lista de enemigos actuales si llega a cero 
    *incrementa el nivel y agrega nuevos enemigos
    */
    public void levels() 
   {
    int x=Greenfoot.getRandomNumber(getWidth());
    int y=Greenfoot.getRandomNumber(getHeight());
    int x1=Greenfoot.getRandomNumber(getWidth());
    int y1=Greenfoot.getRandomNumber(getHeight());
      
     ghostList=getObjects(Ghost.class);
     phantomList=getObjects(Phantom.class);
     bansheeList=getObjects(Banshee.class);
     spiritList=getObjects(Spirit.class);
     
     
    if(h.getLives()==-1)
     {
      updateRecord();   
      Menu menu;         //prueba para fin de juego
      menu= new Menu();
      menu.restaura();
      Greenfoot.stop();
     }
     else
     if(level==1 && ghostList.size()==0)
     {
       appearsGhost();
       appearsPhantom();
       level=2;
       
     }
     else
     if(level==2 && ghostList.size()==0 && phantomList.size()==0)
     {
       addObject(new Health(),x1,y1);
       addObject(new HeroLaser(),x,y);
       appearsGhost();
       appearsBanshee();
       level=3;
     }
     else
     if(level==3  && ghostList.size()==0 && bansheeList.size()==0)
      {
         addObject(new Health(),x1,y1);
         addObject(new HeroLaser(),x,y);
         appearsGhost();
         appearsSpirit();
         level=4;      

      }
     else
     if(level==4 && ghostList.size()==0 && spiritList.size()==0)
     { 
       addObject(new Health(),x1,y1);
       addObject(new HeroBomb(),x,y);
       appearsSpirit();
       appearsPhantom();
       level=5;
       
     }
    else
    if(level==5 && phantomList.size()==0 && spiritList.size()==0)
     {
      addObject(new Health(),x1,y1);
      addObject(new HeroBomb(),x,y);
      appearsSpirit();
      appearsBanshee();
      level=6; 
       
     }

     else
    if(level==6 && bansheeList.size()==0 && spiritList.size()==0)
     {
       updateRecord();
       m=new Message(1);
       addObject(m,getWidth()/2,getHeight()/2);
       m.appearsMessage();  
       Greenfoot.delay(80);  //prueba para fin de juego
       //cambia de mundo cuando gana
       World aux;
       aux=new Menu();
       Greenfoot.setWorld(aux);
     }   
    }
    
    /**
     * actualiza los records
     */
     public void updateRecord()
    {
        if (UserInfo.isStorageAvailable()) 
        {
           UserInfo myInfo = UserInfo.getMyInfo();
           if (h.getPoints() > myInfo.getScore()) {
               myInfo.setScore(h.getPoints());
               myInfo.store();  
           }
        }
    }
    
    /** 
     *@return el nivel actual 
     */
    public int getLevel()
    {
       return level; 
    }
    
    /**
     * @param un numero del 1 al 5 para cambiar el nivel actual
     */
    public void setLevel(int aLevel)
    {
      level=aLevel;  
    }
    
    /**
     * controla el volumen de la musica de fondo del juego y la reproduce ciclicamente
     */
    public void started()
    {
       super.started();
       musicGame.setVolume(90);
       musicGame.playLoop();
    }
    
    /**
     * hace que la musica responda al momento de presionar pause en la interfaz de greenfoot
     */
    public void stopped()
    {
      super.stopped();
      musicGame.pause();
   }
    
    /**
     * cambia la velocidad en que va avanzando el scroll
     * @param un numero entero que determine la velocidad del scroll
     */
    public void cambiaSpeedScroll(int vs)
    {
        scrollSpeed=vs;
    }

    /**
     * metodo que se encarga de redibujar la imagen de fondo simulando el scroll
     */
    public void scroll()
    {
        if(pause)
        {
            if (scrollSpeed!=0)
            {

                if(scrollSpeed > 0 && scrollPosition <= 0) {
                    scrollPosition = getHeight();
                }
                if(scrollSpeed > 0 && scrollPosition >= getHeight()) {
                    scrollPosition = 0;
                }
                scrollPosition += scrollSpeed;
                paint(scrollPosition);

            }

        }
    }
    
     /**
      * dibuja la imagen del scroll
      */
    private void paint(int position)
    {
        GreenfootImage bg = getBackground();
        bg.drawImage(scrollingImage, 0, position);
        bg.drawImage(scrollingImage, 0,  position - scrollingImage.getHeight());
    }

     /**
      * asigna el tamaño a la imagen del scroll
      * @param un ancho y una altura
      */
    private GreenfootImage getScrollingImage(int width, int height)
    {
        GreenfootImage image = new GreenfootImage(width, height);
        for(int x = 0; x < width; x += bgImage.getWidth()) {
            for(int y = 0; y < height; y += bgImage.getHeight()) {
                image.drawImage(bgImage, y, x);

            }
        }
        return image;
    } 

    /**
     * metodo en el cual se sabe si esta en pause el juego
     */
    public boolean getPause()
    {
        return pause;
    }
    
    /**
     * @return el heroe para utilizar sus metodos en las otras clases 
     */
    public Hero getHero()
    {
        return h;
    }
   
    
    /**
     * agrega a la lista todos los enemigos y armas para despues removerlos
     */
    public void cleanWorld()
    {
        this.removeObjects(getObjects(Enemy.class));
        this.removeObjects(getObjects(Guns.class));
        //this.removeObjects(getObjects(Hero.class));
       
        
        
    }

    /**
     * metodo donde se crean el heroe, los letreros de las vidas, salud, puntos y niveles 
     */
    public void prepare()
    {
        addObject(h,getWidth()/2,getHeight()-40);
        addObject(vidas,60,getHeight()-10);
        addObject(puntos,getWidth()-60,getHeight()-10);
        addObject(salud,getWidth()-60,10);
        addObject(nivel,60,10);
      
    }
    
    /**
     * aparece un grupo de naves enemigas de tipo Phantom
     */
    public void appearsPhantom()
    {
        addObject(new PhantomGroup(),getWidth()/2,-80);
    }
    
    /**
     * aparece un grupo de naves enemigas de tipo Banshee
     */
    public void appearsBanshee()
    {
       addObject(new BansheeGroup(),getWidth()/2,getHeight()/3);
          
    }
    
    /**
     * aparece un grupo de naves enemigas de tipo Ghost
     */
    
    public void appearsGhost()
    {
        int posinix = 120;
        int posiniy=-30;
        int tam = 40;
        
         for(int i=0;i<3;i++)
        {
            addObject(new Ghost(),posinix,posiniy);
            posinix = posinix+tam/2+25;
            posiniy = posiniy - tam;
        }
        
    }
    
    /**
     * aparece una nave enemiga jefe de tipo Spirit
     */
    public void appearsSpirit()
    {
        addObject(new Spirit(),getWidth()/2,60);
    }

}
